ts-mochaを使うとECMAScript moduleに依存したファイルでTypeError ERR_UNKNOWN_FILE_EXTENSION: Unknown file extension ".ts"が出てくる。
状況
重要な部分ピックアップ
tsconfig.json
module: CommonJS
moduleResolution: node (デフォルトで記述なし)
package.json
type: CommonJS (デフォルトで記述なし)
code:src/preprocess.test.ts
import neatCsv from "neat-csv"
neatCsv('Header1,Header2\ncell1, cell2\ncell3,cell4')
.then(data => console.log(data))
.catch(e => console.error(e))
code:zsh
❯ npx ts-mocha src/preprocess.test.ts
TypeError ERR_UNKNOWN_FILE_EXTENSION: Unknown file extension ".ts" for /Users/AppleBird/Downloads/timetable/src/preprocess.test.ts この問題は以下の二つの小問題が絡んでいた。
結論としての解決策
Node's ESM loader hooks are experimental and subject to change. ts-node's ESM support is as stable as possible, but it relies on APIs which node can and will break in new versions of node. Thus it is not recommended for production.
しかし実験的機能であることを考慮しないのであれば、--loader module/esmを用いた解決策は強力である。
問題(1)について考える。
- You have installed an ESM dependency but your own code compiles to CommonJS.
Solution: configure your project to compile and execute as native ESM.
つまり、index.jsはindex.mjsとして扱われる。
code:output
require() of ES Module ./timetable/node_modules/neat-csv/index.js from ./timetable/src/neat-csv-tester.ts not supported.
Instead change the require of index.js in ./timetable/src/neat-csv-tester.ts to a dynamic import() which is available in all CommonJS modules.
(2)について考えたかった
色々調べた。
ts-node側で--esmを渡すとうまく実行できた。
※ ファイル名に先立ってこのオプションを渡さないと、--esmが有効にならない。 あるいは、ts-nodeからts-node-esmに切り替えさせる方法もない。
現状の解決法1
現状の解決法2
(1) 以下をtsconfigに付記する。
code:tsconfig.json
"module": "ES2015", //"ES~~"系であれば問題なし。
"moduleResolution": "nodenext",
この上で、importに使うファイルの拡張子に.jsを付記しておく。
(2) そして、以下の設定ファイルを用意した上でmochaを直接使ってテストする。 code:.mocharc.json
{
"require": "ts-node/register",
"loader": "ts-node/esm",
}
現地点(2023-04-04 03:57)で、mocha側のドキュメントにこれの記述がない。 .をファイル名の先頭に先頭につけていることに注意
loaderがないとTypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts"が発生する。
To customize the default module resolution, ...
考慮点
Node's ESM loader hooks are experimental and subject to change. ts-node's ESM support is as stable as possible, but it relies on APIs which node can and will break in new versions of node. Thus it is not recommended for production.
現状は解決策1がもっとも望ましい。
感想
そもそもESMに固執しようとしなければこんなことには... また、TypeScriptにもっと詳しくなれた。
あと、モジュールのブラックボックスを切り開いて解析するという自分の人生初なことも何気にやった。
出来ないと証明できたのでめちゃくちゃスッキリした。よかった〜〜〜....。
hr.icon
02:20 -03:19
次の何の依存も持たないtsファイルをts-mochaに乗せて、mochaへの渡し方が変わるか確認する code:test.ts
console.log("a");
.cts, mts --> いずれも正しく実行される。
type: moduleのありなし
いずれも正しく実行うされる。
あれ〜〜〜となるとts-mochaはESMだからといってmochaに直渡ししているわけではなさそう。 諦めた...。
00:39 - 01:20
何やってるか、大雑把な流れはわかった。